package com.carrent.sxt.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.EnumMap;

/**
 * 生成二维码
 */
public class ZXingCodeEncodeUtils {

    //声明颜色
    private static final int BLACK = 0xFF000000;
    //二维码背景颜色
    private static final int White = 0xFFFFFFFF;

    //二维码格式参数-----写法固定
    private static final EnumMap<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);

    static {
        /**
         * 二维码的纠错级别(排错率),四个级别L(7%),M(15%),Q(25%),H(30%)(最高H)
         */
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //二维码边界空白大小1，2，3，4(4为默认，最大)
        hints.put(EncodeHintType.MARGIN, 1);
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
    }

    /**
     * 生成二维码保存到D盘
     */
    public static void createZXingCodeSaveToDisk(String content, int width, int height, String savePath, String imageType) {
        try {
            BitMatrix encode = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

            //得到二维码的宽度
            int code_width = encode.getWidth();
            int code_height = encode.getHeight();

            //创建图片
            BufferedImage image = new BufferedImage(code_width, code_height, BufferedImage.TYPE_INT_RGB);
            //把二维码的信息保存到图片里面
            for (int i = 0; i < code_width; i++) {
                for (int j = 0; j < code_height; j++) {
                    image.setRGB(i, j, encode.get(i, j) ? BLACK : White);
                }
            }

            //保存到硬盘
            File file = new File(savePath);
            if (!file.exists()) {
                file.createNewFile();
            }
            ImageIO.write(image, imageType, file);
            System.out.println("生成成功");
        } catch (WriterException | IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成二维码图片并返回
     */
    public static BufferedImage createZXingCodeNormal(String content, int width, int height) {
        try {
            BitMatrix encode = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

            //得到二维码的宽度
            int code_width = encode.getWidth();
            int code_height = encode.getHeight();

            //创建图片
            BufferedImage image = new BufferedImage(code_width, code_height, BufferedImage.TYPE_INT_RGB);
            //把二维码的信息保存到图片里面
            for (int i = 0; i < code_width; i++) {
                for (int j = 0; j < code_height; j++) {
                    image.setRGB(i, j, encode.get(i, j) ? BLACK : White);
                }
            }
            return image;
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 生成一张带logo的二维码保存到D盘
     */
    public static void createZXingCodeWithLogoSaveToDisk(String content, int width, int height, String savePath, String imageType, InputStream logoStream) {
        try {
            BufferedImage codeNormal = createZXingCodeNormal(content, width, height);
            if (null != codeNormal) {
                //判断logoStream是否为空
                if (null != logoStream) {
                    //拿到可以操作当前图片的画笔
                    Graphics2D graphics2D = codeNormal.createGraphics();
                    //得到logo图片的对象
                    BufferedImage logoImage = ImageIO.read(logoStream);
                    //得到logo的宽高
                    int old_logo_width = logoImage.getWidth();
                    int old_logo_height = logoImage.getHeight();

                    //拿到二维码的宽高
                    int code_width = codeNormal.getWidth();
                    int code_height = codeNormal.getHeight();

                    //得出logo在二维码里面能存在的最大值
                    int logo_max_width = code_width / 5;
                    int logo_max_height = code_height / 5;

                    //计算logo的可用宽高
                    int logo_width = logo_max_width < old_logo_width ? logo_max_width : old_logo_width;
                    int logo_height = logo_max_height < old_logo_height ? logo_max_height : old_logo_height;
                    //计算logo的开始点的坐标
                    int x = (code_width - logo_width) / 2;
                    int y = (code_height - logo_height) / 2;
                    /**
                     * arg0:图片对象
                     * arg1:开始画的x坐标
                     * arg2：开始画的y坐标
                     * arg3：要画的x长度
                     * arg4：要画的y长度
                     * arg5：null
                     */
                    graphics2D.drawImage(logoImage, x, y, logo_width, logo_height, null);

                    graphics2D.dispose();//让画上去的内容生效
                }
            } else {
                System.out.println("生成失败");
            }

            //保存到硬盘
            File file = new File(savePath);
            if (!file.exists()) {
                file.createNewFile();
            }
            ImageIO.write(codeNormal, imageType, file);
            System.out.println("生成成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成一张带logo的二维码并返回
     */
    public static BufferedImage returnZXingCodeWithLogo(String content, int width, int height, InputStream logoStream) {
        try {
            BufferedImage codeNormal = createZXingCodeNormal(content, width, height);
            if (null != codeNormal) {
                //判断logoStream是否为空
                if (null != logoStream) {
                    //拿到可以操作当前图片的画笔
                    Graphics2D graphics2D = codeNormal.createGraphics();
                    //得到logo图片的对象
                    BufferedImage logoImage = ImageIO.read(logoStream);
                    //得到logo的宽高
                    int old_logo_width = logoImage.getWidth();
                    int old_logo_height = logoImage.getHeight();

                    //拿到二维码的宽高
                    int code_width = codeNormal.getWidth();
                    int code_height = codeNormal.getHeight();

                    //得出logo在二维码里面能存在的最大值
                    int logo_max_width = code_width / 5;
                    int logo_max_height = code_height / 5;

                    //计算logo的可用宽高
                    int logo_width = logo_max_width < old_logo_width ? logo_max_width : old_logo_width;
                    int logo_height = logo_max_height < old_logo_height ? logo_max_height : old_logo_height;
                    //计算logo的开始点的坐标
                    int x = (code_width - logo_width) / 2;
                    int y = (code_height - logo_height) / 2;
                    /**
                     * arg0:图片对象
                     * arg1:开始画的x坐标
                     * arg2：开始画的y坐标
                     * arg3：要画的x长度
                     * arg4：要画的y长度
                     * arg5：null
                     */
                    graphics2D.drawImage(logoImage, x, y, logo_width, logo_height, null);

                    graphics2D.dispose();//让画上去的内容生效
                }
            } else {
                System.out.println("生成失败");
            }
            return codeNormal;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}